package com.sunwayworld.basemodule.rm.train.question.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.sunwayworld.basemodule.rm.train.question.bean.LimsCoreQuestionBean;
import com.sunwayworld.basemodule.rm.train.question.bean.LimsCoreQuestionOptBean;
import com.sunwayworld.basemodule.rm.train.question.dao.LimsCoreQuestionDao;
import com.sunwayworld.basemodule.rm.train.question.service.LimsCoreQuestionOptService;
import com.sunwayworld.basemodule.rm.train.question.service.LimsCoreQuestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.sunwayworld.framework.at.annotation.AuditTrailEntry;
import com.sunwayworld.framework.at.annotation.AuditTrailType;
import com.sunwayworld.framework.audit.aunnotation.Audit;
import com.sunwayworld.framework.audit.constant.AuditConstant;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.context.LocalContextHelper;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.module.mdm.user.bean.CoreUserBean;

@GikamBean
@Repository
public class LimsCoreQuestionServiceImpl implements LimsCoreQuestionService {
    @Autowired
    private LimsCoreQuestionDao limsCoreQuestionDao;
    
    @Autowired
    @Lazy
    private LimsCoreQuestionOptService limsCoreQuestionOptService;
    
    @Override
    @SuppressWarnings("unchecked")
    public LimsCoreQuestionDao getDao() {
        return limsCoreQuestionDao;
    }
    
    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.INSERT)
    @Audit(AuditConstant.INSERT)
    public Long insert(RestJsonWrapperBean wrapper) {
        LimsCoreQuestionBean question = wrapper.parseUnique(LimsCoreQuestionBean.class);
        CoreUserBean currentUser = LocalContextHelper.getLoginUser();
        question.setId(ApplicationContextHelper.getNextIdentity());
        question.setLastUpdatedById(currentUser.getId());
        question.setLastUpdatedByName(currentUser.getUserName());
        question.setLastUpdatedTime(LocalDateTime.now());
        getDao().insert(question);
        return question.getId();
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.UPDATE)
    @Audit(AuditConstant.SAVE)
    public void updateIfChanged(List<LimsCoreQuestionBean> itemList) {
        CoreUserBean currentUser = LocalContextHelper.getLoginUser();
        LocalDateTime currentTime = LocalDateTime.now();
        itemList.forEach(e -> {
            e.setLastUpdatedById(currentUser.getId());
            e.setLastUpdatedByName(currentUser.getUserName());
            e.setLastUpdatedTime(currentTime);
        });
        LimsCoreQuestionService.super.updateIfChanged(itemList);
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.INSERT)
    @Audit(AuditConstant.INSERT)
    public List<Long> clone(RestJsonWrapperBean wrapper) {
        List<LimsCoreQuestionBean> questionList = wrapper.parse(LimsCoreQuestionBean.class);
        if (questionList.isEmpty()) {
            return null;
        }
        
        List<LimsCoreQuestionBean> otherList = questionList.stream().filter(f -> !"shortAnswer".equals(f.getQuestionType())).collect(Collectors.toList());
        List<LimsCoreQuestionBean> shortAnswerList = questionList.stream().filter(f -> "shortAnswer".equals(f.getQuestionType())).collect(Collectors.toList());
        
        CoreUserBean currentUser = LocalContextHelper.getLoginUser();
        LocalDateTime currentTime = LocalDateTime.now();
        List<LimsCoreQuestionBean> questionList4Insert = new ArrayList<>();
        List<Long> idList = new ArrayList<>();
        
        if (!shortAnswerList.isEmpty()) {
            shortAnswerList.forEach(e -> {
                
                LimsCoreQuestionBean question4Insert = new LimsCoreQuestionBean();
                Long id = ApplicationContextHelper.getNextIdentity();
                
                question4Insert.setId(id);
                question4Insert.setQuestionCategory(e.getQuestionCategory());
                question4Insert.setQuestionType(e.getQuestionType());
                question4Insert.setQuestionContent(e.getQuestionContent());
                question4Insert.setAnswer(e.getAnswer());
                question4Insert.setJudgementAnswer(e.getJudgementAnswer());
                question4Insert.setLastUpdatedById(currentUser.getId());
                question4Insert.setLastUpdatedByName(currentUser.getUserName());
                question4Insert.setLastUpdatedTime(currentTime);
                
                idList.add(id);
                questionList4Insert.add(question4Insert);
            });
        }
        
        if (!otherList.isEmpty()) {
            
            List<Long> otherIdList = otherList.stream().map(LimsCoreQuestionBean::getId).collect(Collectors.toList());
            List<LimsCoreQuestionOptBean> otherOptList = limsCoreQuestionOptService.getDao().selectListByOneColumnValues(otherIdList, "QUESTIONID");
            
            List<LimsCoreQuestionOptBean> questionOptList4Insert = new ArrayList<>();
            
            otherList.forEach(e -> {
                
                LimsCoreQuestionBean question4Insert = new LimsCoreQuestionBean();
                Long id = ApplicationContextHelper.getNextIdentity();
                
                question4Insert.setId(id);
                question4Insert.setQuestionCategory(e.getQuestionCategory());
                question4Insert.setAnswer(e.getAnswer());
                question4Insert.setJudgementAnswer(e.getJudgementAnswer());
                question4Insert.setQuestionType(e.getQuestionType());
                question4Insert.setQuestionContent(e.getQuestionContent());
                question4Insert.setLastUpdatedById(currentUser.getId());
                question4Insert.setLastUpdatedByName(currentUser.getUserName());
                question4Insert.setLastUpdatedTime(currentTime);
                
                List<LimsCoreQuestionOptBean> subOtherOptList = otherOptList.stream().filter(f -> f.getQuestionId().equals(e.getId())).collect(Collectors.toList());
                if (!subOtherOptList.isEmpty()) {
                    subOtherOptList.forEach(item -> {
                        LimsCoreQuestionOptBean questionOpt4Insert = new LimsCoreQuestionOptBean();
                        Long optId = ApplicationContextHelper.getNextIdentity();
                        
                        questionOpt4Insert.setId(optId);
                        questionOpt4Insert.setQuestionId(id);
                        questionOpt4Insert.setOptCode(item.getOptCode());
                        questionOpt4Insert.setOptContent(item.getOptContent());
                        
                        questionOptList4Insert.add(questionOpt4Insert);
                    });
                }
                idList.add(id);
                questionList4Insert.add(question4Insert);
            });
            if (!questionOptList4Insert.isEmpty()) {
                limsCoreQuestionOptService.getDao().insert(questionOptList4Insert);
            }
        }
        
        limsCoreQuestionDao.insert(questionList4Insert);
        
        return idList;
    }
}